import paho.mqtt.client as mqtt
import multiprocessing
import queue
import threading
import time
import concurrent.futures
from collections import deque
import uiautomator2 as u2

import random
import json
from urllib.parse import quote
import re
from datetime import datetime
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
from base64 import b64decode
import base64
import binascii
from Crypto.Cipher import PKCS1_v1_5

import sys
import os

current_dir = os.path.dirname(__file__)

parent_dir = os.path.abspath(os.path.join(current_dir, ".."))

sys.path.append(parent_dir)

import automain
import modifydev
import detect

class MQTTSubscriber:
    counter = multiprocessing.Value('i', 0)

    lock = threading.Lock()

    shared_list = []

    def add_to_list(self,value):
        self.lock.acquire()
        try:
            self.shared_list.append(value)
        finally:
            self.lock.release()

    def remove_from_list(self,value):
        self.lock.acquire()
        try:
            self.shared_list.remove(value)
        finally:
            self.lock.release()


    def producer(self,queue, data):
        queue.put(data)


    def consumer(self,queue):
        with open('private', 'rb') as f:
            private_key = RSA.import_key(f.read())
        while True:
            data = queue.get()
            print("Consumed:", data)
            thread = thread = threading.Thread(target=self.thread_function,args=(private_key,data,))
            thread.start()


    def thread_function(self,private_key,encrypted_message):
            cipher_rsa = PKCS1_OAEP.new(private_key)
            encrypted_message =base64.b64decode(encrypted_message)
            decrypted_message = cipher_rsa.decrypt(encrypted_message)
            print("Decrypted message:", decrypted_message)
            eval(decrypted_message)

    q = queue.Queue()

    max_items = 5

    def increment_counter(self,counter):
        counter.value += 1
        print('count=',counter.value)

    def on_connect(self,client, userdata, flags, rc):
        if rc == 0:
            print("Connected to MQTT broker")
        else:
            print("Connection failed")

    def on_disconnect(self,client, userdata, rc):
        print("Disconnected from MQTT broker. Reconnecting...")
        client.reconnect()

    def __init__(self, topic):
        self.topic = topic

        self.client = mqtt.Client()
        self.client.on_connect = self.on_connect
        self.client.on_disconnect = self.on_disconnect
        self.client.username_pw_set("jy", "abc123")

        #self.client.on_connect = on_connect

        self.client.reconnect_delay_set(min_delay=1, max_delay=120)

        self.client.connect("47.108.253.212", 1883, 60)
        self.client.on_message = self.on_message

        consumer_thread = threading.Thread(target=self.consumer, args=(self.q,))
        consumer_thread.start()

        self.task_queue = deque(maxlen=3)

        self.executor = concurrent.futures.ThreadPoolExecutor(max_workers=3)


    def on_message(self, client, userdata, message):
        self.increment_counter(self.counter)
        producer_thread = threading.Thread(target=self.producer, args=(self.q, message.payload.decode()))
        producer_thread.start()


    def send_message(self, topic,message):
        self.client.publish(topic, message)

    def start(self):
        self.client.subscribe(self.topic)

        self.client.loop_forever()

def generate_RSA_key_pair():
        private_key = rsa.generate_private_key(
            public_exponent=65537,
            key_size=2048,
            backend=default_backend()
            )

        public_key = private_key.public_key().public_bytes(
            encoding=serialization.Encoding.PEM,
            format=serialization.PublicFormat.SubjectPublicKeyInfo
            )

        private_key = private_key.private_bytes(
            encoding=serialization.Encoding.PEM,
            format=serialization.PrivateFormat.TraditionalOpenSSL,
            encryption_algorithm=serialization.NoEncryption()
        )

        return public_key, private_key


def decrypt_rsa(encrypted_data, private_key):

    rsa_private_key = private_key

    cipher = PKCS1_v1_5.new(rsa_private_key)

    decrypted_data = b''
    offset = 0
    while offset < len(encrypted_data):
        chunk = encrypted_data[offset:offset + 256]
        decrypted_chunk = cipher.decrypt(chunk, None)
        decrypted_data += decrypted_chunk
        offset += 256

    return decrypted_data.decode('utf-8')


if __name__ == "__main__":

    subscriber = MQTTSubscriber("myt")

    subscriber.send_message('hjyc','sssssssssssssssss')

    # 启动消息接收
    subscriber.start()